package cn.xfyun.example.controller;


import cn.xfyun.example.dto.WSRequest;
import cn.xfyun.example.util.CreateContext;
import cn.xfyun.example.config.AppConfig;
import cn.xfyun.example.util.JwtUtil;
import cn.xfyun.example.util.SparkService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.stereotype.Component;

@Component
public class SparkWebSocketHandler extends TextWebSocketHandler {


    private static class SessionData {
        private boolean isAuthenticated = false;
        private String jwtToken;
        private String userId;
        private final long connectionEstablishedTime = System.currentTimeMillis();
        private String interviewId;
        private String field;
        private WebSocketSession session;

        public WebSocketSession getSession() {
            return session;
        }

        public void setSession(WebSocketSession session) {
            this.session = session;
        }

        public boolean isAuthenticated() {
            return isAuthenticated;
        }

        public void setAuthenticated(boolean authenticated) {
            isAuthenticated = authenticated;
        }

        public String getJwtToken() {
            return jwtToken;
        }

        public void setJwtToken(String jwtToken) {
            this.jwtToken = jwtToken;
        }

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public long getConnectionEstablishedTime() {
            return connectionEstablishedTime;
        }

    }

    private static final Map<String, SessionData> sessionDataMap = new ConcurrentHashMap<>();

    @Autowired
    private CreateContext createContext;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private SparkService sparkService;

    @Autowired
    private JwtUtil jwtUtil;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        String sessionId = session.getId();
        SessionData data = sessionDataMap.get(sessionId);


        // 1. 检查是否超时（连接建立后3分钟内未发送JWT）
        long currentTime = System.currentTimeMillis();
        if (currentTime - data.getConnectionEstablishedTime() > 3 * 60 * 1000) {
            session.sendMessage(new TextMessage("Timeout: JWT not received within 3 minutes."));
            session.close();
            return;
        }

        // 2. 如果尚未认证，处理JWT验证
        if (!data.isAuthenticated()) {
            if (!jwtUtil.isTokenValid(payload)) {
                session.sendMessage(new TextMessage("Invalid JWT token."));
                session.close();
                return;
            }

            String userId = jwtUtil.extractUserId(payload);
            data.setJwtToken(payload);
            data.setUserId(userId);
            data.setAuthenticated(true);

            session.sendMessage(new TextMessage("Authentication successful."));
            return; // 认证成功后不再继续处理其他逻辑
        }

        // 0. 处理 "END" 消息
        if ("END".equalsIgnoreCase(payload.trim())) {
            session.close();
            return;
        }

        // 2. 解析首次消息中的 interviewId 和 field
        try {
            WSRequest initialWSRequest = objectMapper.readValue(payload, WSRequest.class);
            String interviewId = initialWSRequest.getInterviewId();
            String field = initialWSRequest.getField();
            if (interviewId == null || field == null || field.isEmpty()) {
                session.sendMessage(new TextMessage("Invalid input: missing interviewId or field"));
                return;
            }
            System.out.println("interviewId:" + interviewId);
            System.out.println("field:" + field);
            // 4. 调用 CreateContext 生成问题
            String question = createContext.collectQuestionsAndAnswers(interviewId, field);
            System.out.println("生成的问题:" + question);

            // 5. 调用外部 Chat API 并转发结果
            Map<String, String> result = sparkService.askQuestion(
                    appConfig.getSparkAppid(),
                    appConfig.getSparkApiSecret(),
                    appConfig.getSparkApiKey(),
                    question,
                    session.getId(),
                    interviewId
            );


        } catch (Exception e) {
            session.sendMessage(new TextMessage("Error processing request: " + e.getMessage()));
            e.printStackTrace();
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String sessionId = session.getId();
        SessionData data = new SessionData();
        data.setSession(session);
        sessionDataMap.put(sessionId, data);
        super.afterConnectionEstablished(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String sessionId = session.getId();
        sessionDataMap.remove(sessionId);
        super.afterConnectionClosed(session, status);
    }

    public static void sendMessageToClient(String sessionId, String message) throws IOException {
        SessionData data = sessionDataMap.get(sessionId);
        if (data != null) {
            WebSocketSession webSocketSession = data.getSession();
            if (webSocketSession != null && webSocketSession.isOpen()) {
                // 直接发送消息，移除对getExecutor()的调用
                webSocketSession.sendMessage(new TextMessage(message));
            }
        }
    }
}
